import {Message} from '@arco-design/web-vue'
import axios from 'axios'
import {APIRes} from "@/types/global";
import router from '@/router';

export interface HttpResponse<T = unknown> {
  status: number
  msg: string
  code: number
  data: T
}

let isRefreshing = false
let reqList: any[] = [];

if (import.meta.env.VITE_SERVER_URL) {
  axios.defaults.baseURL = import.meta.env.VITE_SERVER_URL + '/api'
  axios.defaults.withCredentials = true
  axios.defaults.timeout = 10000
}

axios.interceptors.request.use(
  (config: any) => {
    if (import.meta.env.VITE_CAN_LOG === 'true') {
      if (config.hasOwnProperty('params')) {
        console.log('axios ->', config.method, config.url, JSON.stringify(config.params))
      } else if (config.hasOwnProperty('data')) {
        console.log('axios ->', config.method, config.url, JSON.stringify(config.data))
      } else {
        console.log('axios ->', config.method, config.url)
      }
    }
    const token = localStorage.getItem('access_token')
    if (token) {
      config.headers.Authorization = 'Bearer ' + token
    }
    return config
  },
  (error) => {
    return Promise.reject(error)
  }
)
// add response interceptors
axios.interceptors.response.use(
  async (response: any) => {
    const res = response.data
    if (import.meta.env.VITE_CAN_LOG === 'true') {
      let log = JSON.stringify(res)
      if (log.includes('data:image')) {
        log = '[base64 data]'
      }
      console.log('axios <-', response.config.method, response.config.url, log)
    }
    if (res.code === 401) {
      //尝试刷新token
      if (!isRefreshing) {
        isRefreshing = true
        const res = await axios.post('/admin/refresh-token') as APIRes
        isRefreshing = false
        if (res.code === 0) {
          //刷新token成功,重新执行先前的请求
          localStorage.setItem('access_token', res.data.access_token)
          return axios.request(response.config)
        } else {
          //刷新token失败，跳到登录
          reqList = []
          router.push({
            name: 'login',
            query: {
              redirect: router.currentRoute.value.name as string,
            },
          }).then();
          return Promise.reject()
        }
      } else {
        //正在刷新 token，将请求加入队列
        return new Promise(resolve => {
          let exist = false
          for (let i = 0; i < reqList.length; i++) {
            if (reqList[i].config.url === response.config.url) {
              exist = true
              break
            }
          }
          if (!exist) {
            reqList.push(() => {
              resolve(axios.request(response.config))
            })
          }
        })
      }
    }
    return res
  },
  (error) => {
    Message.error({
      content: error.msg || 'Request Error',
      duration: 5 * 1000,
    })
    return Promise.reject(error)
  }
)
